# -*- coding: utf-8 -*-
# Houdini To Arnold
# Copyright (C) 2013 Erkan Ozgur Yilmaz
#
# This file is part of Houdini To Arnold.
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation;
# version 2.1 of the License.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA


class DeclaredAttribute(object):
    """A simple storage class for DeclaredAttributes
    """

    def __init__(self, name, type, value):
        self.name = name
        self.type = type
        self.value = value

    def to_ass(self):
        """the ass representation
        """
        template = """ declare %(name)s %(type)s
 %(name)s %(value)s"""
        return template % self.__dict__


class Base(object):
    """This is the base class for the other nodes
    """
    __prefix__ = "base"

    def __init__(self, **kwargs):
        self.__dict__['params'] = {}
        self.__dict__['declared_attributes'] = []
        #self.declared_attributes = []
        #self.params.update(kwargs)
        pass

    def __getattr__(self, item):
        """return the attribute from the params
        """
        try:
            return self.__dict__[item]
        except KeyError:
            try:
                return self.params[item]
            except KeyError:
                # convert it to an AttributeError
                raise AttributeError(
                    "'%(class_name)s' object has no "
                    "attribute '%(attribute_name)s'" % {
                        'class_name': self.__class__.__name__,
                        'attribute_name': item
                    }
                )

    def __setattr__(self, key, value):
        """set parameters
        """
        if 'params' not in self.__dict__:
            self.__dict__['params'] = {}
        self.params[key] = value

    def from_houdini(self, path):
        """generates data directly from the given houdini node with the path

        :param str path: The path of the houdini node
        """
        raise NotImplementedError()

    def to_ass(self):
        """returns the ass representation of the node
        """
        # render all the params with their values to a string
        # the template
        ass_template = """%(prefix)s
{
%(attributes)s
}

"""
        attribute_template = " %(attr)s %(value)s"

        ass_data_storage = []

        # start with the name attribute
        name = None
        if 'name' in self.params:
            name = self.params.pop('name')
            ass_data_storage.append(
                attribute_template % {'attr': 'name', 'value': name}
            )

        # parameters
        for key in self.params.keys():
            ass_data_storage.append(
                attribute_template % {'attr': key, 'value': self.params[key]}
            )

        # declared attributes
        for declared_attr in self.declared_attributes:
            ass_data_storage.append(declared_attr.to_ass())

        # restore name
        if name:
            self.name = name

        # merge in to one
        return ass_template % {
            'prefix': self.__prefix__,
            'attributes': '\n'.join(ass_data_storage)
        }

    def declare_attribute(self, name, type, value):
        """declares a new attribute
        """
        self.declared_attributes.append(
            DeclaredAttribute(name, type, value)
        )

    def _to_str(self, value):
        """concatenates the given value to string
        """
        if isinstance(value, list):
            return ' '.join(map(str, value))
        elif isinstance(value, tuple):
            return ' '.join('%s' * len(value)) % value


class aiFactory(object):
    """Node factory for arnold.aiFactory

    Generates Arnold nodes based on Houdini node types.
    """
    pass
